import React, { useCallback, useRef, useState } from "react";
import {
  IconTitle,
  Radio,
  Input,
  Icon,
  Button,
  Modal,
  FormatMessage,
  Tooltip,
  Select,
  Terminal,
} from "components";
import _ from "lodash/object";
import { emptyDbConn, emptyImportExcel, getDemoDbConnect } from "../../../lib/datasource_util";
import {
  openFileOrDirPath,
  connectDB,
  showItemInFolder,
  getLogPath,
} from "../../../lib/middle";

import "./style/index.less";
import { getPrefix } from "../../../lib/prefixUtil";

const Option = Select.Option;

export default React.memo(
  ({ prefix, dataSource, config, dataChange, lang }) => {
    const url = getDemoDbConnect();
    const dataTypeSupports = _.get(dataSource, "profile.dataTypeSupports", []);
    const yearSupports = _.get(dataSource, "profile.yearSupports", []);
    const timeTypeSupports = _.get(dataSource, "profile.timeType", []);
    const entitySupports = _.get(dataSource, 'entities');
    console.log("entitySupports", entitySupports);
    const defaultDb = _.get(
      dataSource,
      "profile.default.db",
      dataTypeSupports[0]
    );
    const defaultYear = yearSupports[0];
    const [dbConn, updateDbConn] = useState(dataSource?.dbConn || []);
    const [defaultConn, updateDefaultConn] = useState(() => {
      return (
        dbConn.filter(
          (d) => d.defKey === dataSource?.profile?.default?.dbConn
        )[0]?.defKey || ""
      );
    });
    const [dataMatch, updateDataMatch] = useState([]);
    const { properties = {}, defName } =
      dbConn.filter((d) => d.defKey === defaultConn)[0] || {};
    const propertiesRef = useRef(null);
    propertiesRef.current = properties;
    const defaultConnChange = (e) => {
      const defaultData = dbConn.filter((d) => d.defKey === e.target.value)[0];
      updateDefaultConn(defaultData.defKey);
      updateDataMatch(defaultData.dataMatch);
      dataChange && dataChange(defaultData.defKey, "profile.default.dbConn");
    };
    const currentPrefix = getPrefix(prefix);

    const onChangeDataMatch = (e, index ,name) => {
      const tempDataMatch = dataMatch[index];
      const value = e.target.value;
      if(name === 'dataTable'){
        tempDataMatch.entity = value;
      }else{
        tempDataMatch.sheet = value;
      }
      console.log('onChangeDataMatch', dataMatch );
      updateDataMatch([...dataMatch]);
    }

    
    const dbChange = (e, name, key) => {
      const newData = dbConn.map((d) => {
        if (d.defKey === key) {
          return {
            ...d,
            [name]: e.target.value,
            properties:
              name === "type"
                ? {
                    driver_class_name:
                      url[e.target.value?.toLocaleLowerCase()]?.driverClass ||
                      "",
                    url: url[e.target.value?.toLocaleLowerCase()]?.url || "",
                    password: "",
                    username: "",
                  }
                : d.properties,
          };
        }
        return d;
      });
      updateDbConn(newData);
      dataChange && dataChange(newData, "dbConn");
    };
    const addDataMatch = (e) =>{
        console.log('dataMatch' , e);
        dataMatch.push({
          sheet : '',
          entity: ''
        });
        const tempData = [...dataMatch];
        updateDataMatch(tempData);
        const index = dbConn.findIndex((d) => d.defKey === defaultConn);
        const tempNewData = dbConn[index];
        tempNewData.dataMatch = [...dataMatch];
        updateDbConn(dbConn);
        console.log('dbConn', dbConn);
    }
    const addConn = () => {
      const empty = {
        ...emptyImportExcel,
        defKey: Math.uuid(),
        dataMatch: []
      };
      const newData = dbConn.concat(empty);
      updateDbConn(newData);
      updateDefaultConn(empty.defKey);
      updateDataMatch(empty.dataMatch);
      dataChange && dataChange(empty.defKey, "profile.default.dbConn");
      dataChange && dataChange(newData, "dbConn");
    };
    const deleteConn = () => {
      const index = dbConn.findIndex((d) => d.defKey === defaultConn);
      const newDefaultIndex =
        index === dbConn.length - 1 ? index - 1 : index + 1;
      const newData = dbConn.filter((d) => d.defKey !== defaultConn);
      updateDbConn(newData);
      updateDefaultConn(dbConn[newDefaultIndex]?.defKey || "");
      dataChange &&
        dataChange(
          dbConn[newDefaultIndex]?.defKey || "",
          "profile.default.dbConn"
        );
      dataChange && dataChange(newData, "dbConn");
    };
    const onChange = (e, name) => {
      const newData = dbConn.map((d) => {
        if (d.defKey === defaultConn) {
          return {
            ...d,
            properties: {
              ...(d.properties || {}),
              [name]: e.target.value,
            },
            dataMatch : [...d.dataMatch]
          };
        }
        return d;
      });
      updateDbConn(newData);
      dataChange && dataChange(newData, "dbConn");
    };
    const selectJarFile = () => {
      openFileOrDirPath(
        [
          {
            name: FormatMessage.string({ id: "excelConnect.filePath" }),
            extensions: ["jar"],
          },
        ],
        ["openFile"]
      )
        .then((res) => {
          onChange(
            {
              target: {
                value: res,
              },
            },
            "customer_driver"
          );
        })
        .catch((err) => {
          Modal.error({
            title: FormatMessage.string({ id: "openDirError" }),
            message: err.message || err,
          });
        });
    };

    const selectExcelFile = () => {
      openFileOrDirPath(
        [
          {
            name: FormatMessage.string({ id: "excelConnect.filePath" }),
            extensions: ["xlsx, xls"],
          },
        ],
        ["openFile"]
      )
        .then((res) => {
          onChange(
            {
              target: {
                value: res,
              },
            },
            "customer_driver"
          );
        })
        .catch((err) => {
          Modal.error({
            title: FormatMessage.string({ id: "openDirError" }),
            message: err.message || err,
          });
        });
    };

    const test = useCallback((e, btn) => {
      if (
        Object.keys(propertiesRef.current)
          .filter((p) => p !== "customer_driver")
          .some((p) => !propertiesRef.current[p])
      ) {
        Modal.error({
          title: FormatMessage.string({ id: "optFail" }),
          message: FormatMessage.string({ id: "formValidateMessage" }),
        });
      } else {
        btn && btn.updateStatus("loading");
        connectDB(
          dataSource,
          config,
          {
            ...propertiesRef.current,
            lang,
          },
          "PingLoadDriverClass",
          (result) => {
            btn && btn.updateStatus("normal");
            if (result.status === "FAILED") {
              const termReady = (term) => {
                term.write(result.body);
              };
              Modal.error({
                bodyStyle: { width: "80%" },
                contentStyle: { width: "100%", height: "100%" },
                title: FormatMessage.string({ id: "dbConnect.connectError" }),
                message: (
                  <div>
                    <div style={{ textAlign: "center" }}>
                      <FormatMessage id="dbConnect.log" />
                      <a onClick={showItemInFolder}>{getLogPath()}</a>
                    </div>
                    <Terminal termReady={termReady} />
                  </div>
                ),
              });
            } else {
              Modal.success({
                title: FormatMessage.string({ id: "dbConnect.connectSuccess" }),
                message: `${result.body}`,
              });
            }
          }
        );
      }
    }, []);
    const jdbcHelp = (
      <div className={`${currentPrefix}-dbconnect-example-config`}>
        {Object.keys(url).map((o) => {
          return (
            <div
              key={o}
              className={`${currentPrefix}-dbconnect-example-config-item`}
            >
              <div
                className={`${currentPrefix}-dbconnect-example-config-item-header`}
              >
                {`${url[o].defKey} ${FormatMessage.string({
                  id: "dbConnect.configExample",
                })}↓`}
              </div>
              <div
                className={`${currentPrefix}-dbconnect-example-config-item-content-label`}
              >
                driver_class:
                <span
                  className={`${currentPrefix}-dbconnect-example-config-item-content-value`}
                >
                  {url[o].driverClass}
                </span>
              </div>
              <div
                className={`${currentPrefix}-dbconnect-example-config-item-content-label`}
              >
                url:
                <span
                  className={`${currentPrefix}-dbconnect-example-config-item-content-value`}
                >
                  {url[o].url}
                </span>
              </div>
            </div>
          );
        })}
      </div>
    );
    return (
      <div className={`${currentPrefix}-dbconnect`}>
        <div
          style={{ width: defaultConn ? "50%" : "100%" }}
          className={`${currentPrefix}-dbconnect-left`}
        >
          <div className={`${currentPrefix}-dbconnect-left-header`}>
            <span className={`${currentPrefix}-dbconnect-left-header-opt`}>
              <IconTitle
                type="fa-plus"
                onClick={addConn}
                title={FormatMessage.string({ id: "dbConnect.add" })}
              />
              <IconTitle
                title={FormatMessage.string({ id: "dbConnect.delete" })}
                type="fa-minus"
                onClick={deleteConn}
                disable={!defaultConn}
                style={{ opacity: !defaultConn ? 0.48 : 1 }}
              />
            </span>
            <span className={`${currentPrefix}-dbconnect-left-header-desc`}>
              {defaultConn ? (
                <span>
                  <FormatMessage id="dbConnect.defaultDbConnectDesc" />
                  {defName}
                </span>
              ) : (
                <FormatMessage id="dbConnect.defaultDbConnectEmpty" />
              )}
            </span>
          </div>
          <div
            className={`${currentPrefix}-list ${currentPrefix}-dbconnect-left-list`}
          >
            {dbConn.length > 0 ? (
              dbConn.map((conn) => {
                return (
                  <div
                    key={conn.defKey}
                    className={`${currentPrefix}-list-item`}
                  >
                    <span className={`${currentPrefix}-list-item-com`}>
                      <Radio
                        value={conn.defKey}
                        onChange={defaultConnChange}
                        checked={defaultConn === conn.defKey}
                      />
                    </span>
                    <span className={`${currentPrefix}-list-item-com`}>
                      <Select
                        notAllowEmpty
                        defaultValue={defaultYear}
                        allowClear={false}
                        onChange={(e) => dbChange(e, "type", conn.defKey)}
                      >
                        {yearSupports.map((year) => (
                          <Option key={year} value={year}>
                            {year}
                          </Option>
                        ))}
                      </Select>
                    </span>
                  </div>
                );
              })
            ) : (
              <div className={`${currentPrefix}-list-empty`}>
                <FormatMessage id="dbConnect.emptyConnect" />
              </div>
            )}
          </div>
        </div>
        {defaultConn && (
          <div className={`${currentPrefix}-dbconnect-right`}>
            <div className={`${currentPrefix}-form-item`}>
              <span
                className={`${currentPrefix}-form-item-label`}
                title={FormatMessage.string({ id: "excelConnect.file" })}
              >
                <FormatMessage id="excelConnect.file" />
                <Tooltip
                  placement="top"
                  title={FormatMessage.string({
                    id: "dbConnect.customDriverPlaceholder",
                  })}
                  force
                >
                  <span className={`${currentPrefix}-form-item-label-help`}>
                    <Icon type="icon-xinxi" />
                  </span>
                </Tooltip>
              </span>
              <span className={`${currentPrefix}-form-item-component`}>
                <Input
                  placeholder={FormatMessage.string({
                    id: "excelConnect.filePath",
                  })}
                  onChange={(e) => onChange(e, "customer_driver")}
                  value={properties.customer_driver || ""}
                  suffix={
                    <span
                      className={`${currentPrefix}-dbconnect-opt`}
                      onClick={selectExcelFile}
                    >
                      <Icon
                        type="fa-ellipsis-h"
                        title={FormatMessage.string({ id: "openFile" })}
                      />
                    </span>
                  }
                />
              </span>
            </div>
            {/* //选择年线 */}
            <div className={`${currentPrefix}-form-item`}>
              <span
                className={`${currentPrefix}-form-item-label`}
                title={FormatMessage.string({ id: "excelConnect.timeType" })}
              >
                <span className={`${currentPrefix}-form-item-label-require`}>
                  {}
                </span>
                <FormatMessage id="excelConnect.timeType" />
                <Tooltip placement="left" title={jdbcHelp} force>
                  <span className={`${currentPrefix}-form-item-label-help`}>
                    <Icon type="icon-xinxi" />
                  </span>
                </Tooltip>
              </span>
              <span className={`${currentPrefix}-form-item-component`}>
                <Select
                  notAllowEmpty
                  defaultValue={defaultYear}
                  allowClear={false}
                  onChange={(e) => dbChange(e, "type", conn.defKey)}
                >
                  {timeTypeSupports.map((timeType) => (
                    <Option key={timeType.key} value={timeType.value}>
                      {timeType.key}
                    </Option>
                  ))}
                </Select>
              </span>
            </div>
            {/* 数据匹配 */}
            <div className={`${currentPrefix}-form-item`}>
              <span
                className={`${currentPrefix}-form-item-label`}
                title={FormatMessage.string({ id: "excelConnect.dataMatch" })}
              >
                <span className={`${currentPrefix}-form-item-label-require`}>
                  {}
                </span>
                <FormatMessage id="excelConnect.dataMatch" />
                <Tooltip placement="left" title={jdbcHelp} force>
                  <span className={`${currentPrefix}-form-item-label-help`}>
                    <Icon type="icon-xinxi" />
                  </span>
                </Tooltip>
              </span>
              <span
                className={`${currentPrefix}-form-item-component`}
                style={{ flexDirection: "inherit" }}
              >
                <Button
                  style={{ margin: "0", marginLeft: "10px" }}
                  onClick={(e) => addDataMatch(e)}
                >
                  新增
                </Button>
              </span>
            </div>
            {/* //动态添加的select */}
            {
              dataMatch.map((data, index) =>(
                <div className={`${currentPrefix}-form-item`}>
                  <span
                    className={`${currentPrefix}-form-item-label`}
                    title={FormatMessage.string({ id: "excelConnect.dataMatch" })}
                  ></span>
                  <span
                    className={`${currentPrefix}-form-item-component`}
                    style={{ flexDirection: "row" }}
                  >
                    <span style={{ marginRight: "5px", width: "48%" }}>
                      <Select
                        notAllowEmpty
                        defaultValue={'Sheet'}
                        allowClear={false}
                        value={data.sheet}
               
                      ></Select>
                    </span>
                    <span style={{ marginRight: "5px", width: "48%" }}>
                      <Select
                        notAllowEmpty
                        defaultValue={'数据表'}
                        allowClear={false}
                        value={data.entity}
                        onChange={(e) => onChangeDataMatch(e, index ,'dataTable')}
                        style={{ verticalAlign: "5px"}}
                      >
                         {entitySupports.map((entity) => (
                          <Option key={entity.defKey} value={entity.defKey}>
                            {entity.defKey}
                          </Option>
                         ))}
                      </Select>
                    </span>
                  </span>
                </div>
              ))
            }
            <div className={`${currentPrefix}-dbconnect-right-button`}>
              <Button onClick={test}>
                {FormatMessage.string({ id: "dbConnect.test" })}
              </Button>
            </div>
          </div>
        )}
      </div>
    );
  }
);
